package middlewares

import (
	"net/http"
	"os"
	"strconv"
	"time"

	"github.com/golang-jwt/jwt/v5"
	echojwt "github.com/labstack/echo-jwt/v4"
	"github.com/labstack/echo/v4"
)

// 自定义 JWT 声明
type jwtCustomClaims struct {
	Uid  string `json:"uid"`
	Role string `json:"role"`
	jwt.RegisteredClaims
}

// 生成 JWT token
func GenerateToken(uid int, role string) (string, error) {
	// Set custom claims
	claims := &jwtCustomClaims{
		strconv.Itoa(uid),
		role,
		jwt.RegisteredClaims{
			ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Hour * 168)),
		},
	}

	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)

	return token.SignedString([]byte(os.Getenv("JWT_SECRET")))
}

// JWT 中间件
func JwtMiddleware() echo.MiddlewareFunc {
	return echojwt.WithConfig(echojwt.Config{
		NewClaimsFunc: func(c echo.Context) jwt.Claims {
			return new(jwtCustomClaims)
		},
		SigningKey: []byte(os.Getenv("JWT_SECRET")),
		ErrorHandler: func(c echo.Context, err error) error {
            // 在这里自定义返回的 HTTP 状态码，例如返回 401 Unauthorized
            return c.JSON(http.StatusUnauthorized, map[string]interface{}{
				"code": http.StatusUnauthorized,
                "msg": "未登录或登录凭证无效",
				"data": nil,
            })
        },
		SuccessHandler: func(c echo.Context) {
			// 从上下文中获取 JWT
            user := c.Get("user").(*jwt.Token)
			claims := user.Claims.(*jwtCustomClaims)

			uid, err := strconv.Atoi(claims.Uid)
			if err != nil || (uid <= 0) {
				uid = 0
			}

			c.Set("uid", uid)
		},
	})
}

// 用户角色验证 中间件
func CheckRoleMiddleware(requiredRole string) echo.MiddlewareFunc {
	return func(next echo.HandlerFunc) echo.HandlerFunc {
		return func(c echo.Context) error {
			// Get the user from the JWT middleware
			user := c.Get("user")
			if user == nil {
				return echo.NewHTTPError(http.StatusUnauthorized, "Missing or invalid token")
			}

			// Extract claims
			token := user.(*jwt.Token)
			claims, ok := token.Claims.(*jwtCustomClaims)
			if !ok {
				return echo.NewHTTPError(http.StatusUnauthorized, "Invalid token claims")
			}

			// 检查用户角色
			if claims.Role != requiredRole {
				return echo.NewHTTPError(http.StatusUnauthorized, "Access denied: insufficient permissions")
			}

			return next(c)
		}
	}
}

// 用户可选登录 中间件
func OptionalUserLoginMiddleware() echo.MiddlewareFunc {
	return echojwt.WithConfig(echojwt.Config{
		NewClaimsFunc: func(c echo.Context) jwt.Claims {
			return new(jwtCustomClaims)
		},
		SigningKey: []byte(os.Getenv("JWT_SECRET")),

		ErrorHandler: func(c echo.Context, err error) error {
            // 不管是否登录，都允许访问
			return nil
        },
		
		/*
			ContinueOnIgnoredError allows the next middleware/handler to be called when ErrorHandler decides to ignore the error (by returning `nil`).
		*/
		ContinueOnIgnoredError: true,
		
		SuccessHandler: func(c echo.Context) {
			// 从上下文中获取 JWT
            user := c.Get("user").(*jwt.Token)
			claims := user.Claims.(*jwtCustomClaims)

			role := claims.Role
			
			uid := 0
			if role == "user" {
				uidTmp, err := strconv.Atoi(claims.Uid)
				if err == nil && (uidTmp > 0) {
					uid = uidTmp
				}
			}
			
			c.Set("uid", uid)
		},
	})
}

// 允许 JWT 可选中间件 （未登录/已登录都可以）
func OptionalJWTMiddleware(next echo.HandlerFunc) echo.HandlerFunc {
    return func(c echo.Context) error {
        authHeader := c.Request().Header.Get("Authorization")
        if authHeader != "" {
            // 有 JWT，执行 JWT 认证
            jwtHandler := OptionalUserLoginMiddleware()(next)
            return jwtHandler(c)
        }
        return next(c) // 没有 JWT，直接跳过
    }
}